/*
 * @Description: axios 封装
 * @Autor: Alfred
 * @Date: 2022-04-07 17:55:23
 * @FilePath: /v3Demo/src/service/request/index.ts
 */

import type {AxiosError, AxiosInstance, AxiosRequestConfig, AxiosResponse} from 'axios'
import axios from 'axios'
import type {RequestConfig, RequestInterceptors} from './types.ts'
import {ElMessage} from 'element-plus'

class Request {
	//  axios 实例
	instance: AxiosInstance
	// 拦截器对象
	interceptorsObj?: RequestInterceptors

	constructor(config: RequestConfig) {
		this.instance = axios.create(config)
		this.interceptorsObj = config.interceptors

		// 全局请求拦截器
		this.instance.interceptors.request.use(
			(res: AxiosRequestConfig) => {
				// console.log('全局请求')
				return res
			},
			(err: any) => err
		)

		// 使用实例拦截器
		this.instance.interceptors.request.use(
			this.interceptorsObj?.requestInterceptors,
			this.interceptorsObj?.requestInterceptorsCatch
		)
		// 使用实例响应拦截器
		this.instance.interceptors.response.use(
			this.interceptorsObj?.responseInterceptors,
			this.interceptorsObj?.responseInterceptorsCatch
		)

		// 全局响应拦截器
		this.instance.interceptors.response.use(
			// 因为我们接口的数据都在res.data下，所以我们直接返回res.data
			(res: AxiosResponse) => {
				// console.log('全局拦截器', res)
				return res.data
			},
			(err: AxiosError) => {
				// 拦截状态吗
				httpErrorStatusHandle(err)
			}
		)
	}

	request<T>(config: RequestConfig): Promise<T> {
		return new Promise((resolve, reject) => {
			this.instance
				.request<any, T>(config)
				.then(res => {
					resolve(res)
				})
				.catch((err: any) => {
					reject(err)
				})
		})
	}
}

function httpErrorStatusHandle(err: AxiosError) {
	let message = ''
	if (err && err.response) {
		switch (err.response.status) {
			case 302:
				message = '接口重定向了！'
				break
			case 400:
				message = '参数不正确！'
				break
			case 401:
				message = '您未登录，或者登录已经超时，请先登录！'
				break
			case 403:
				message = '您没有权限操作！'
				break
			case 404:
				message = `请求地址出错: ${err.response.config.url}`
				break // 在正确域名下
			case 408:
				message = '请求超时！'
				break
			case 409:
				message = '系统已存在相同数据！'
				break
			case 500:
				message = '服务器内部错误！'
				break
			case 501:
				message = '服务未实现！'
				break
			case 502:
				message = '网关错误！'
				break
			case 503:
				message = '服务不可用！'
				break
			case 504:
				message = '服务暂时无法访问，请稍后再试！'
				break
			case 505:
				message = 'HTTP版本不受支持！'
				break
			default:
				message = '异常问题，请联系管理员！'
				break
		}
	}
	if (err.message.includes('timeout')) {
		message = '网络请求超时！'
	}
	if (err.message.includes('Network')) {
		message = window.navigator.onLine ? '服务端异常！' : '您断网了！'
	}
	ElMessage({
		type: 'error',
		message
	})
}

export default Request
